//
//  Crate.m
//  SSE
//
//  Created by Matt Roman on 10/11/07.
//  Copyright 2007 OU. All rights reserved.
//

#import "Crate.h"

static GLubyte front[] = {0,1,5,4};
static GLubyte back[] = {2,3,7,6};
static GLubyte left[] = {8,9,10,11};
static GLubyte right[] = {12,13,14,15};
static GLubyte top[] = {16,17,18,19};
const GLvoid * indices[] = {front,right,back,left,top};
// cube ///////////////////////////////////////////////////////////////////////
//		 Z
//       |
//		 |       
//    v7----- v6 
//   /|      /|
//  v4------v5|	RIGHT
//  | |     | |
//  | |v3---|-|v2
//  |/   .  |/ -------> X
//  v0------v1
//	  FRONT

@implementation Crate

- (id)initCrateAlpha:(GLfloat)angle 
				   X:(GLfloat)x 
				   Y:(GLfloat)y 
				   Z:(GLfloat)z 
				   L:(float)l
				   W:(float)w
				   H:(float)h
{
	int j,k,s;
	float hyp,gamma;
	Vector3f tempV1,tempV2,tempV3;
	const GLubyte *face;
	
	[super init];
	alpha = angle;
	position.x = x;
	position.y = y;
	position.z = z;
	color[1] = 1.0;
	color[3] = 0.8;
	length = l;
	width = w;
	height = h;
	
	hyp = sqrt(l*l+w*w)/2.0;
	gamma = atan((w/2.0)/(l/2.0));
	
	box[0]=(float)position.x - hyp*cos(gamma + alpha);		// v0
	box[1]=(float)position.y - hyp*sin(gamma + alpha);
	box[2]=position.z;
	
	box[3]=(float)position.x - hyp*cos(PI-gamma+alpha);		// v1
	box[4]=(float)position.y - hyp*sin(PI-gamma+alpha);
	box[5]=position.z;
	
	box[6]=(float)position.x + hyp*cos(gamma + alpha);		// v2
	box[7]=(float)position.y + hyp*sin(gamma + alpha);
	box[8]=position.z;
	
	box[9]= (float)position.x + hyp*cos(PI-gamma+alpha);		// v3	
	box[10]=(float)position.y + hyp*sin(PI-gamma+alpha);
	box[11]=position.z;
	
	box[12]=box[0];		// v4
	box[13]=box[1];
	box[14]=h+position.z;
	
	box[15]=box[3];		// v5
	box[16]=box[4];
	box[17]=h+position.z;
	
	box[18]=box[6];		// v6
	box[19]=box[7];
	box[20]=h+position.z;
	
	box[21]=box[9];		// v7
	box[22]=box[10];
	box[23]=h+position.z;
	
	
	box[24]=box[0];		// LEFT
	box[25]=box[1];
	box[26]=box[2];
	
	box[27]=box[12];
	box[28]=box[13];
	box[29]=box[14];
	
	box[30]=box[21];
	box[31]=box[22];
	box[32]=box[23];
	
	box[33]=box[9];
	box[34]=box[10];
	box[35]=box[11];
	
	box[36]=box[3];		// RIGHT
	box[37]=box[4];
	box[38]=box[5];
	
	box[39]=box[6];
	box[40]=box[7];
	box[41]=box[8];
	
	box[42]=box[18];
	box[43]=box[19];
	box[44]=box[20];
	
	box[45]=box[15];
	box[46]=box[16];
	box[47]=box[17];
	
	box[48]=box[12];		// TOP
	box[49]=box[13];
	box[50]=box[14];
	
	box[51]=box[15];
	box[52]=box[16];
	box[53]=box[17];
	
	box[54]=box[18];
	box[55]=box[19];
	box[56]=box[20];
	
	box[57]=box[21];
	box[58]=box[22];
	box[59]=box[23];
	
	for(j=0;j<5;j++)
	{
		s=j+1;
		if(j == 4)
		{
			tempV3.a = 0;
			tempV3.b = 0;
			tempV3.c = 1;
		}
		else
		{
			if(j == 3) s = 0;
				PntstoVectorPtr(box+j*3,box+3*s,&tempV1);
				PntstoVectorPtr(box+j*3,box+12+3*j,&tempV2);
				NormalizeCross(&tempV1,&tempV2,&tempV3);
		}
		face = indices[j];
		for(k=0;k<4;k++)
		{	
			norms[face[k]*3]   = tempV3.a;
			norms[face[k]*3+1] = tempV3.b;
			norms[face[k]*3+2] = tempV3.c;
		}
					
	}
	return self;
}

- (void)drawCrate
{
	int j;
	
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
	glEnableClientState(GL_NORMAL_ARRAY);			// ENABLE THE USE OF OBJECT ARRAYS
	glEnableClientState(GL_VERTEX_ARRAY);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	
	glNormalPointer(GL_FLOAT, 0, norms);
	glVertexPointer(3, GL_FLOAT, 0, box);
	glColor4fv(color);
	
	for(j=0;j<5;j++)
	{		
		glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, indices[j]);
	}
	
	///////////////////////////////////////////////////////////////////
	// DRAWS A POINT AT THE CENTER OF THE OBSTACLE
	//glPointSize(3.0);
	//glBegin(GL_POINTS);
	//	glColor4f(WHITE);
	//	glVertex3f(box[0],box[1],box[2]);
	//glEnd();
	
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glDisableClientState(GL_NORMAL_ARRAY);			// DISABLE THE USE OF OBJECT ARRAYS
	glDisableClientState(GL_VERTEX_ARRAY);
}

- (void)setColorR:(GLfloat)r G:(GLfloat)g B:(GLfloat)b A:(GLfloat)a
{
	color[0] = r;
	color[1] = g;
	color[2] = b;
	color[3] = a;
}

- (Point3f)getPosition
{
	return position;
}

- (float)getLength
{
	return length;
}

- (float)getWidth
{
	return width;
}

- (float)getAlpha
{
	return alpha;
}
@end
